<template>
  <div>
    <button @click="change(item.component)" v-for="item in list">{{ item.name }}</button>
    <!-- 动态组件 -->
    <component :is="flag"></component>
  </div>
</template>
<script setup lang="ts">
// 导入组件
import { markRaw, reactive, ref } from 'vue'
import A from './components/A/index.vue'
import B from './components/B/index.vue'

// markRaw 参数为一对象，返回值为增加了 _v_skip 属性的对象
// 对于设置了 _v_skip 属性的对象，在 Proxy 代理时，会跳过该对象，不进行代理
// 一般用于创建包含非响应式对象的数据，对于特定对象单独调用 markRaw 跳过代理
// markRaw(object)

// 动态组件：即可以被切换显示的组件
// 使用 <component :is="componentObj">
// 当该标签的 is 属性绑定为特定的组件实例时，会将整个标签替换为该组件标签
// 通过设置响应式数据 componentObj 和设定切换该响应式数据的函数，可以切换组件显示

// 定义接口
interface Item {
  name: string
  component: Object
}
// 定义用于循环渲染的数据
const list = reactive<Item[]>([
  // 对于组件实例，不需要进行响应式数据 Proxy 代理
  // 调用 markRaw 方法，打上标记后会跳过代理
  { name: 'A', component: markRaw(A) },
  { name: 'B', component: markRaw(B) },
])
// 定义控制组件切换的数据
const flag = ref<Object>(A)
// 定义切换组件的函数
const change = (item: Object) => {
  flag.value = item
}
</script>
<style scoped></style>
